We are migrating the bug tracker to github Issues. This is now the preferred way to report NASM bugs.

Self-registration is disabled due to spam issue (mail gorcunov@gmail.com or hpa@zytor.com to create an account)

Bug 3392535 - Duplicate label with same value is silently ignored
Summary: Duplicate label with same value is silently ignored
Status: CLOSED FIXED
Alias: None
Product: NASM
Classification: Unclassified
Component: Assembler (show other bugs)
Version: 2.14.xx
Hardware: All All
: Medium minor
Assignee: nobody
URL:
Depends on:
Blocks:
 
Reported: 2018-11-27 12:18 PST by E. C. Masloch
Modified: 2018-12-14 01:16 PST (History)
5 users (show)

Obtained from: From OS distribution
Generated by: ---
Bug category:
Observed for: ---
Regression: ---
Regression since:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description E. C. Masloch 2018-11-27 12:18:19 PST
NASM 2.14 silently allows the same label to be defined multiple times, if the address value is the same. Assuming this is an unintended "feature", this should be disallowed, as it was in NASM 2.13.

Test case:

~/test/nasm/20181127$ cat test2.asm 

test1:
test2:
test1:

testA equ 1
testB equ 2
testA equ 1

~/test/nasm/20181127$ nasm -v
NASM version 2.14
~/test/nasm/20181127$ nasm test2.asm
~/test/nasm/20181127$ ./nasm -v
NASM version 2.13.03 compiled on Feb  7 2018
~/test/nasm/20181127$ ./nasm test2.asm
test2.asm:4: error: symbol `test1' redefined
test2.asm:8: error: symbol `testA' redefined
~/test/nasm/20181127$
Comment 1 H. Peter Anvin 2018-12-07 13:36:12 PST
If the value is the same, is there any downside to allowing this?  It ought to make include files easier.

However, this is probably related to bug 3392534, and the resolution of this might depend on the resolution of that bug.
Comment 2 Chang S. Bae 2018-12-07 14:32:26 PST
Looks like it begins with the labeling mechanism changes in 2.14:
(98578071: 'Cleanup of label renaming infrastructure, add subsection support')
Comment 3 H. Peter Anvin 2018-12-10 13:40:16 PST
After careful consideration I have come to believe this is desirable behavior. As such, I have retained this behavior when fixing bug 3392534 and documented it.
Comment 4 E. C. Masloch 2018-12-11 05:37:55 PST
Here's a patch atop the current nasm-2.14.xx branch (commit 54aac9d3c1b501050e6e75823317a4e34d6b2066) that adds a suppressible, default-off warning for label redefinition with same value:

diff --git a/asm/error.c b/asm/error.c
index 73db7443..3205c729 100644
--- a/asm/error.c
+++ b/asm/error.c
@@ -70,6 +70,7 @@ const struct warning warnings[ERR_WARN_ALL+1] = {
     {"unknown-warning", "unknown warning in -W/-w or warning directive", false},
     {"negative-rep", "regative %rep count", true},
     {"phase", "phase error during stabilization", false},
+    {"label-redef", "label redefined with same value", false},
 
     /* THIS ENTRY MUST COME LAST */
     {"all", "all possible warnings", false}
diff --git a/asm/labels.c b/asm/labels.c
index a073f798..f29ae157 100644
--- a/asm/labels.c
+++ b/asm/labels.c
@@ -521,6 +521,23 @@ void define_label(const char *label, int32_t segment,
                        lptr->defn.label,
                        created ? "defined" : "changed");
         }
+    } else if (lastdef && lastdef == lpass) {
+        int32_t saved_line = 0;
+        const char *saved_fname = NULL;
+
+        /*
+         * Defined elsewhere in the program, seen in this pass, no change.
+         */
+        nasm_error(ERR_WARNING | ERR_WARN_LABEL_REDEF | ERR_PASS2,
+                   "label `%s' redefined with same value",
+                   lptr->defn.label);
+
+        src_get(&saved_line, &saved_fname);
+        src_set(lptr->defn.def_line, lptr->defn.def_file);
+        nasm_error(ERR_NOTE | ERR_WARN_LABEL_REDEF | ERR_PASS2,
+                   "label `%s' originally defined here",
+                   lptr->defn.label);
+        src_set(saved_line, saved_fname);
     }
 
     lptr->defn.segment = segment;
diff --git a/asm/nasm.c b/asm/nasm.c
index d1a4fe0d..9811ee76 100644
--- a/asm/nasm.c
+++ b/asm/nasm.c
@@ -1805,7 +1805,12 @@ static void nasm_verror_vc(int severity, const char *fmt, va_list ap)
 static inline bool is_valid_warning(int severity)
 {
     /* Not a warning at all */
-    if ((severity & ERR_MASK) != ERR_WARNING)
+    if ((severity & ERR_MASK) != ERR_WARNING &&
+        /*
+         * ERR_NOTE is only subject to being treated like a warning
+         * if a warning index other than 0 (other) is given.
+         */
+        ((severity & ERR_MASK) != ERR_NOTE || WARN_IDX(severity) == 0))
         return false;
 
     return WARN_IDX(severity) < ERR_WARN_ALL;
diff --git a/include/error.h b/include/error.h
index f7e38af3..af29fd37 100644
--- a/include/error.h
+++ b/include/error.h
@@ -115,9 +115,10 @@ static inline vefunc nasm_set_verror(vefunc ve)
 #define ERR_WARN_UNK_WARNING	WARN(20) /* unknown warning */
 #define ERR_WARN_NEG_REP	WARN(21) /* negative repeat count */
 #define ERR_WARN_PHASE		WARN(22) /* phase error in pass 1 */
+#define ERR_WARN_LABEL_REDEF	WARN(23) /* label redefined with same value */
 
 /* The "all" warning acts as a global switch, it must come last */
-#define ERR_WARN_ALL            23 /* Do not use WARN() here */
+#define ERR_WARN_ALL            24 /* Do not use WARN() here */
 
 struct warning {
     const char *name;
Comment 5 Cyrill Gorcunov 2018-12-13 01:02:13 PST
Thanks! As to me -- this patch might useful. I'll take more precise look on the weekend hopefully.
Comment 6 H. Peter Anvin 2018-12-14 01:16:27 PST
This is now implemented upstream, although I didn't use the patch per se.